package com.cis467.mrball.backend;


import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;

import android.os.Environment;
import android.util.Xml;

import com.cis467.mrball.HighScore;
import com.cis467.mrball.parts.Level;

public final class LocalContent {
	
    public static String basePath = "MB/";
	public static String builderPath = "MB_builder/";
	public static String downloadPath = "MB_download/";
	public static String corePath = "MB_core/";
	
	public static String highScoreFile = "mb_hs";
	public static String idFile = "junk";
	
	

	
	/*
	 * ********** Level FUNTIONS ********************
	 */
	// TODO remove once the DB is implemented
	public static Level get_Level(String path) throws Exception{
		String xml = "";

		 xml = openFile(path);
		 return convertXML(xml);
	}
	
	// TODO user Level.toString()?
	public static String createXML(Level submitLevel) {
		return submitLevel.toString();
	}

	
	
    /*
     * *********** HS FUNCTIONS *********************
     */
	

	public static HighScore[] getHighScores() throws Exception {
		String hs = openFile( highScoreFile );
		HighScore myhs[] = buildHS(hs);
		return myhs;
	}

	private static HighScore[] buildHS(String hs) {
		
		String lines[] = hs.split("\n");
		HighScore myhs[]= new HighScore[lines.length];
		
		String on, ol;
		double time;

		
		for(int i = 0; i < lines.length; i++){
			String savedScore[] = lines[i].split("-");
			time = Double.parseDouble( savedScore[1] );
			on = savedScore[0].split(":")[0];
			ol = savedScore[0].split(":")[1];
			
			myhs[i]= new HighScore(ol,on,time);			
		}
		
		return myhs;
	}

	


	public static void set_NewHS(HighScore new_HighScore) throws Exception {
		String myHS = null;
		HighScore[] score = null;
		try{
			myHS = openFile(highScoreFile);
		}catch( Exception e){
			e.printStackTrace();
		}
				
		if(myHS == null){
			saveFile(new_HighScore.toString(), "", highScoreFile );
		} else {
			score = buildHS(myHS);
			HighScore found = find(new_HighScore, score);
			
			if( found != null){
				if( found.getTime() > new_HighScore.getTime())
					found.setLevelTime(new_HighScore.getTime());
				myHS = toHighScoreString(score);

			}else{
				myHS = toHighScoreString(addScore(score,new_HighScore));
			}
			saveFile(myHS, "", highScoreFile);
		}
		
	}
	
	private static HighScore[] addScore(HighScore[] score, HighScore new_HighScore) {
		HighScore[] newHS = new HighScore[score.length + 1];
		for (int i = 0; i < score.length; i++){
			newHS[i] = score[i];
		}
		newHS[newHS.length-1] = new_HighScore;
		return newHS;
		
	}


	private static String toHighScoreString(HighScore[] score) {
		String ret = score[0].toString();
		
		for(int i = 1; i < score.length; i++){
			ret += "\n" +score[i].toString();
		}
		return ret;
	}


	private static HighScore find(HighScore new_HighScore, HighScore[] score) {
		boolean found = false;
		HighScore ret = null;
		for( int i = 0; i < score.length && !found ; i++){
			if(score[i].equals(new_HighScore)){
				found = true;
				ret = score[i];
				
			}
		}
		return ret;
	}
	
	/*
	 * ************** XML CONVERSION ******************
	 */
	// TODO it doesn't really make sense for this method to be here, because it's also used for converting remote content
	// TODO move this to the level object
	public static Level convertXML(String xml){
		
		
		MyXmlContentHandler myhandler = new MyXmlContentHandler();
		try{
			Xml.parse(xml, myhandler);
		}catch(Exception e){
			e.printStackTrace();
		}

		Level mylevel = myhandler.getLevel();
		
		try{
			mylevel.setup(true);
		}catch(Exception e){
			e.printStackTrace();
		}
	
		return mylevel;
	}
	
	public static boolean istype(String element, String line){
		return line.contains(element);
	}
	
    /*
     * ****************** TOOLS / UTIL *******************
     */
	
	// TODO remove this once database is implemented
	public static void saveFile(String fcontents, String pathName, String filename) throws Exception {
		String folderpath = Environment.getExternalStorageDirectory()+"/"+basePath+pathName;
		File dir = new File(folderpath);
		try{
			dir.mkdirs();
		}catch(Exception e){
			throw new Exception("mkdirs exception");
		}
			
		File level = new File(folderpath+filename);
		try{
			level.createNewFile();
		}catch(Exception e){
			throw new Exception("create file exception\n "+folderpath);
		}
		
		
		BufferedWriter bw = new BufferedWriter(
								new OutputStreamWriter(
									new FileOutputStream(level.getPath()), 
														"utf8"), 8192);
		bw.write(fcontents);
			
		bw.close();		
	}
	
	// TODO investigate alternative methods of initially deploying core levels. this method may not be needed
	public static String openFile(String name) throws Exception{
		
		String location = Environment.getExternalStorageDirectory() +"/"+ basePath + name;
		File myfile = new File(location);
		String read = "";
		int r = -1;
		
		
		FileReader input = new FileReader(myfile);
		
		char[] buffer = new char[99999];
		r = input.read(buffer);

		if( r != -1)
			read = new String(buffer);
		
		input.close();
		return read;				
	}

	// TODO Remove this when DB is implemented
	public static void createDirectories() {
		String location = Environment.getExternalStorageDirectory() +"/"+ basePath;
		File download = new File(location+downloadPath);
		File builder = new File(location+builderPath);
		File core = new File(location+corePath);
		download.mkdirs();
		builder.mkdirs();
		core.mkdirs();
			
	}

	// TODO Store as shared preference
	public static String getUserID() {
		String retval;
		try{
			
			retval = openFile("junk").split("\n")[0]; 
		}catch(Exception e){
			retval = "";
		}
		
		return retval;
	}

	// TODO rewrite as DB query and move to SQLiteHelper
	public static ArrayList<Level> get_coreLevels() {
		String coreFolder = Environment.getExternalStorageDirectory() +"/"+ basePath;
		coreFolder += corePath;
		File c = new File(coreFolder);
		File[] myfiles = c.listFiles();
		
		ArrayList<Level> retval = new ArrayList<Level>();
		
		for( int i = 0 ; i < myfiles.length; i++){
			
			try {
				retval.add(convertXML(openFile(corePath + myfiles[i].getName())));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		 
		return retval;
	}

	// TODO rewrite as DB query and move to SQLiteHelper
	public static ArrayList<Level> get_dlLevels() {
		
		String downloadFolder = Environment.getExternalStorageDirectory() +"/"+ basePath;
		downloadFolder += downloadPath;
		File d = new File(downloadFolder);
		File[] myfiles = d.listFiles();
		
		ArrayList<Level> retval = new ArrayList<Level>();
		
		for( int i = 0 ; i < myfiles.length; i++){
			
			try {
				retval.add(convertXML(openFile(downloadPath + myfiles[i].getName())));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		 
		return retval;
	}

	// TODO rewrite as DB query and move to SQLiteHelper
	public static ArrayList<Level> get_buildLevels() {
		String builderFolder = Environment.getExternalStorageDirectory() +"/"+ basePath;
		builderFolder += builderPath;
		File b = new File(builderFolder);
		File[] myfiles = b.listFiles();
		
		ArrayList<Level> retval = new ArrayList<Level>();
		
		for( int i = 0 ; i < myfiles.length; i++){
			
			try {
				retval.add(convertXML(openFile(builderPath + myfiles[i].getName())));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		 
		return retval;

	}

	// TODO Store as shared preference
	public static String getUserKey() {
		String retval;
		try{
			
			retval = openFile("junk").split("\n")[1]; 
		}catch(Exception e){
			retval = "";
		}
		
		return retval;
	}
	
}
